/**
 * 广寒宫
 * 网址:www.guanghangong.xyz
 */
package org.moon.framework.autoconfigure.tenant;

import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
import org.moon.framework.autoconfigure.config.SystemConfig;
import org.moon.framework.autoconfigure.datasource.routing.DynamicDataSource;
import org.moon.framework.autoconfigure.datasource.routing.DynamicDataSourceContextHolder;
import org.moon.framework.autoconfigure.mybatisplus.props.JdbcProperties;
import org.moon.framework.autoconfigure.tenant.aop.TenantDataSourceAnnotationAspect;
import org.moon.framework.autoconfigure.tenant.aop.TenantDataSourceGlobalAspect;
import org.moon.framework.autoconfigure.tenant.props.MoonTenantProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import java.util.HashMap;
import java.util.Map;

/**
 * 多租户数据源
 * @author moon
 */
@Configuration
@ConditionalOnProperty(value = "moon.tenant.type", havingValue = "datasource")
@EnableConfigurationProperties({JdbcProperties.class, MoonTenantProperties.class})
@Slf4j
public class TenantDataSourceAutoConfiguration {

    public TenantDataSourceAutoConfiguration(){
        log.info("系统已开启数据源租户模式....");
    }

    @Autowired
    private SystemConfig systemConfig;

    @Bean
    public TenantDataSourceAnnotationAspect tenantDataSourceAnnotationAspect(MoonTenantProperties moonTenantProperties){
        if(moonTenantProperties.getDatasourceGlobal()){
            return null;
        }
        log.info("系统已开启@TenantDS注解切换租户数据源....");
        return new TenantDataSourceAnnotationAspect(systemConfig);
    }

    /**
     * 在service层开启全局多租户数据源
     */
    @Bean
    @ConditionalOnProperty(value = "moon.tenant.datasource-global", havingValue= "true")
    public TenantDataSourceGlobalAspect tenantDataSourceGlobalAspect(){
        log.info("系统已关闭@TenantDs注解，已为所有的@Service开启租户数据源切换，可通过@NonDS排除....");
        return new TenantDataSourceGlobalAspect(systemConfig);
    }

    /**
     * 初始化主数据源
     * 主数据源在系统启动时读取配置文件中的连接信息完成成初始化，目的是为了方面在后期切换时没有指定目标数据源，则默认切回主数据源
     */
    @Bean("dataSource")
    @Primary
    public DynamicDataSource multipleDataSource (JdbcProperties jdbcProperties) {
        log.info("数据源租户模式，主数据源初始化完成....");
        Map< Object, Object > targetDataSources = new HashMap<>();
        HikariDataSource hikariDataSource = DynamicDataSourceContextHolder.buildDataSource(jdbcProperties);
        String dsName = "default";
        targetDataSources.put(dsName, hikariDataSource );
        DynamicDataSource dynamicMultipleDataSource = new DynamicDataSource(hikariDataSource,targetDataSources);
        return dynamicMultipleDataSource;
    }
}
